/**
 * 项目管理路由
 *
 * Created by snowingsea on 2020/02/06.
 */
const moment = require('moment');
const middleware = require('./../middleware');
const projects = require('./../../models/projects');
const projectHistories = require('./../../models/project-histories');
const PhoenixError = require('./../../models/phoenix-error');

/**
 * 获取项目信息
 * @param req
 * @param res
 * @param next
 */
function getProject(req, res, next) {
  projects.updateVisitTime(req.params.projectId)
    .then(() => {
      req.$project.visitAt = moment();
      res.json(projects.getJson(req.$project));
    })
    .catch((err) => {
      next(new PhoenixError(err));
    });
}

/**
 * 批量获取项目列表
 * @param req
 * @param res
 * @param next
 */
function getProjects(req, res, next) {
  const resProjects = {
    pagination: req.filter,
  };
  const options = projects.getProjectOptions(req.query);
  options.$or = [
    { creatorId: req.$token.userId },
    { sharedUserGroup: req.$token.userId },
  ];
  projects.filter(req.filter, options)
    .then((data) => {
      resProjects.projects = data.map((project) => projects.getSummaryJson(project));
      return projects.getCount(options);
    })
    .then((count) => {
      resProjects.pagination.total = count;
      res.json(resProjects);
    })
    .catch((err) => {
      next(new PhoenixError(err));
    });
}

/**
 * 测试人员添加个人项目
 * @param req
 * @param res
 * @param next
 */
function addProject(req, res, next) {
  const {
    projectName,
    initVersion,
    description,
    language,
    projectType,
  } = req.query;
  if (!projectName) {
    next(new PhoenixError('invalid request', 'Missing parameters. "projectName" is required'));
    return;
  }
  if (!language) {
    next(new PhoenixError('invalid request', 'Missing parameters. "language" is required'));
    return;
  }
  if (!projectType) {
    next(new PhoenixError('invalid request', 'Missing parameters. "projectType" is required'));
    return;
  }

  let project;
  projects.addProject(
    req.$token.userId,
    projectName,
    language,
    projectType,
    initVersion,
    description,
    req.$me,
    req.$license,
  )
    .then((res) => {
      project = res;
      const projectId = res._id; // eslint-disable-line no-underscore-dangle
      const { createVersion } = projectHistories.kind;
      return projectHistories.addHistory(projectId, createVersion, { versionName: initVersion });
    })
    .then(() => {
      res.json(projects.getJson(project));
    })
    .catch((err) => {
      if (err.code === 11000) {
        err = new PhoenixError('conflict', 'project already exist');
      }
      next(new PhoenixError(err));
    });
}

/**
 * 删除个人项目
 * @param req
 * @param res
 * @param next
 */
function removeProject(req, res, next) {
  projects.removeProject(req.params.projectId, req.$project)
    .then(() => {
      res.status(204).json();
    })
    .catch((err) => {
      next(new PhoenixError(err));
    });
}

/**
 * 批量删除项目
 * @param req
 * @param res
 * @param next
 */
function removeProjects(req, res, next) {
  const options = projects.getProjectOptions(req.query);
  options.creatorId = req.$token.userId;
  projects.getProjects(req.query, options)
    .then((resProjects) => {
      const promises = resProjects.map((project) => {
        const projectId = project._id; // eslint-disable-line no-underscore-dangle
        return projects.removeProject(projectId, project);
      });
      return Promise.all(promises);
    })
    .then(() => {
      res.status(204).json();
    })
    .catch((err) => {
      next(new PhoenixError(err));
    });
}

/**
 * 编辑项目
 * @param req
 * @param res
 * @param next
 */
function updateProject(req, res, next) {
  const { projectId } = req.params;
  projects.updateProject(projectId, { ...req.query, ...req.body }, req.$project)
    .then(() => projects.getProject(projectId))
    .then((project) => {
      res.json(projects.getJson(project));
    })
    .catch((err) => {
      if (err.code === 11000) {
        err = new PhoenixError('conflict', 'project name already exist');
      }
      next(new PhoenixError(err));
    });
}

/**
 * 获取项目单条历史信息
 * @param req
 * @param res
 * @param next
 */
function getProjectHistory(req, res, next) { // eslint-disable-line no-unused-vars
  res.json(projectHistories.getJson(req.$projectHistory));
}

/**
 * 获取项目历史列表
 * @param req
 * @param res
 * @param next
 */
function getProjectHistories(req, res, next) {
  const resProjectHistories = {
    pagination: req.filter,
  };
  const options = { projectId: req.$project._id }; // eslint-disable-line no-underscore-dangle
  projectHistories.filter(req.filter, options)
    .then((data) => {
      resProjectHistories.histories = data.map((history) => projectHistories.getJson(history));
      return projectHistories.getCount(options);
    })
    .then((count) => {
      resProjectHistories.pagination.total = count;
      res.json(resProjectHistories);
    })
    .catch((err) => {
      next(new PhoenixError(err));
    });
}

/**
 * Export model definition object.
 */
module.exports = (app, prefix) => {
  const projectsURL = `${prefix}/projects.json`;
  const projectURL = `${prefix}/projects/:projectId.json`;
  const projectHistoryURL = `${prefix}/project-histories/:projectHistoryId.json`;
  const projectHistoriesURL = `${prefix}/projects/:projectId/histories.json`;

  // 获取项目信息
  app.get(projectURL, middleware.user.requireTokenUnexpired);
  app.get(projectURL, middleware.user.requireAvailable);
  app.get(projectURL, middleware.user.requireTester);
  app.get(projectURL, middleware.project.requireProjectExist);
  app.get(projectURL, middleware.project.requireProjectAccess);
  app.get(projectURL, getProject);

  // 获取项目列表
  app.get(projectsURL, middleware.user.requireTokenUnexpired);
  app.get(projectsURL, middleware.user.requireAvailable);
  app.get(projectsURL, middleware.user.requireTester);
  app.get(projectsURL, middleware.splitFilter);
  app.get(projectsURL, getProjects);

  // 添加项目
  app.post(projectsURL, middleware.user.requireTokenUnexpired);
  app.post(projectsURL, middleware.user.requireAvailable);
  app.post(projectsURL, middleware.user.requireTester);
  app.post(projectsURL, middleware.license.requireLicenseExist);
  app.post(projectsURL, addProject);

  // 删除项目
  app.delete(projectURL, middleware.user.requireTokenUnexpired);
  app.delete(projectURL, middleware.user.requireAvailable);
  app.delete(projectURL, middleware.user.requireTester);
  app.delete(projectURL, middleware.project.requireProjectExist);
  app.delete(projectURL, middleware.project.requireProjectAccess);
  app.delete(projectURL, removeProject);

  // 批量删除项目
  app.delete(projectsURL, middleware.user.requireTokenUnexpired);
  app.delete(projectsURL, middleware.user.requireAvailable);
  app.delete(projectsURL, middleware.user.requireTester);
  app.delete(projectsURL, removeProjects);

  // 编辑项目信息
  app.put(projectURL, middleware.user.requireTokenUnexpired);
  app.put(projectURL, middleware.user.requireAvailable);
  app.put(projectURL, middleware.user.requireTester);
  app.put(projectURL, middleware.project.requireProjectExist);
  app.put(projectURL, middleware.project.requireProjectAccess);
  app.put(projectURL, updateProject);

  // 获取项目单条历史信息
  app.get(projectHistoryURL, middleware.user.requireTokenUnexpired);
  app.get(projectHistoryURL, middleware.user.requireAvailable);
  app.get(projectHistoryURL, middleware.user.requireTester);
  app.get(projectHistoryURL, middleware.project.requireProjectHistoryExist);
  app.get(projectHistoryURL, middleware.project.requireProjectAccess);
  app.get(projectHistoryURL, getProjectHistory);

  // 获取项目历史列表
  app.get(projectHistoriesURL, middleware.user.requireTokenUnexpired);
  app.get(projectHistoriesURL, middleware.user.requireAvailable);
  app.get(projectHistoriesURL, middleware.user.requireTester);
  app.get(projectHistoriesURL, middleware.project.requireProjectExist);
  app.get(projectHistoriesURL, middleware.project.requireProjectAccess);
  app.get(projectHistoriesURL, middleware.splitFilter);
  app.get(projectHistoriesURL, getProjectHistories);
};
